---
title: OBRetentionService consumption
summary: How ProcessOB3PRetention constructs, calls, and holds the OBRetentionService proxy, with resilience and error handling findings.
status: draft
owner: ProcessOB3PRetention team
last_reviewed: 2026-10-22
---

# OBRetentionService consumption

The application constructs `HylandOutBoundContractClient` once inside the `OnBaseService` constructor, calls its single operation once per batch, and never closes it. Nothing wraps the call in a retry, timeout, or cancellation policy.

## Reference style

| Field | Value |
| --- | --- |
| Mechanism | `service-reference` (svcutil) |
| Declared in | `ProcessOB3PRetention/ProcessOB3PRetention.csproj` (`WCFMetadata` and `WCFMetadataStorage` items) |
| Generated artifacts | `ProcessOB3PRetention/Connected Services/OBRetentionService/Reference.cs` and `Reference.svcmap` |
| Target framework | .NET Framework 4.8 |
| Regeneration command | Visual Studio "Update Service Reference" on `Connected Services\OBRetentionService` |

## Construction

```csharp
_client = new HylandOutBoundContractClient(
    "BasicHttpBinding_HylandOutBoundContract", 
    environmentService.GetConfigSetting("ProcessOB3PRetention.WSPEndPointUrl"));
```

| Step | Requirement |
| --- | --- |
| Endpoint address | Configuration key `ProcessOB3PRetention.WSPEndPointUrl`, read through `IEnvironmentService.GetConfigSetting`. See [endpoint resolution](architecture.md#endpoint-resolution) |
| Binding | Named binding configuration `BasicHttpBinding_HylandOutBoundContract` in `ProcessOB3PRetention/App.config`, selected by the endpoint name literal |
| Credentials | None. No client credential type is set and none is assigned in code |
| Initialization | Single constructor call; no follow-up property assignment |

## Endpoint configuration

| Setting | Value | Source | Changeable without a rebuild |
| --- | --- | --- | --- |
| Endpoint address | `prod`: `https://onbase25prod.corp.saif.com/ThirdPartyArchivalService_Integration/SoapService.svc/SOAP11`; `entqa`: `https://onbase25qa.corp.saif.com/ThirdPartyArchivalService_Integration/SoapService.svc/SOAP11`; `npuat`: `https://onbase25npuat.corp.saif.com/ThirdPartyArchivalService_Integration/SoapService.svc/SOAP11` | Setting `ProcessOB3PRetention.WSPEndPointUrl`, seeded for each track by `environmentSettings/settings.yml` | Yes |
| Binding configuration | `BasicHttpBinding_HylandOutBoundContract` | `ProcessOB3PRetention/App.config` | Yes |
| Security mode | `Transport` | `ProcessOB3PRetention/App.config` | Yes |

## Resilience

| Concern | Finding | Configurable by consumer | Source | Tech debt |
| --- | --- | --- | --- | --- |
| Timeout | None configured; not specified, transport default applies | Yes, on the binding in `ProcessOB3PRetention/App.config` | `ProcessOB3PRetention/App.config` (no timeout attribute) | Yes |
| Retry | None configured | No | — | Yes |
| Circuit breaking | None configured | No | — | Yes |
| Thread safety | Not determined from source; calls are sequential on one thread** | — | `ProcessOB3PRetention/ThirdPartyRetentionProcessor.cs` | No |
| Cancellation | Not supported; the call is synchronous with no cancellation token | — | `ProcessOB3PRetention/Services/OnBaseService.cs:40` | Yes |
| Message size limits | None set; not specified, transport default applies | Yes, on the binding in `ProcessOB3PRetention/App.config` | `ProcessOB3PRetention/App.config` | No |

There is no retry, so a transient failure surfaces directly to the caller and ends the run at the first failing batch. The consumer would have to add its own retry, set binding timeouts, or add an outer timeout; none exists today. See [Tech debt](tech-debt.md).

## Disposal

| Aspect | Finding |
| --- | --- |
| Disposal performed | None. Neither `Close()` nor `Abort()` is called |
| Faulted channel handled | No. A faulted channel is neither recovered nor released before the process exits |
| Wrapper responsibility | No disposal found. `OnBaseService` does not implement `IDisposable` |
| Source | `ProcessOB3PRetention/Services/OnBaseService.cs` |

## Error handling at the call sites

| Call site | Exception types caught | Logged | Outcome |
| --- | --- | --- | --- |
| `OnBaseService.ProcessRetention` calling `ArchiveDocument` (`ProcessOB3PRetention/Services/OnBaseService.cs:40`) | None | No | Propagates unchanged |
| `ThirdPartyRetentionProcessor.Execute` calling `ProcessRetention` (`ProcessOB3PRetention/ThirdPartyRetentionProcessor.cs:52`) | `System.Exception` around the whole batch loop | Yes, `LogService.WriteError` with the message only | Rethrown with `throw ex;`, which resets the stack trace. The run ends at the first failing batch; batches completed earlier were already archived and marked processed |
| `OnBaseService` constructor (`ProcessOB3PRetention/Services/OnBaseService.cs:17`) | None | No | Propagates during Autofac resolution in `Program.CreateApplication`, before `Execute`, outside its `try` and `catch`* |

No call site distinguishes a declared fault, a communication failure, or a timeout; the WSDL declares no faults. Process exit behavior on an unhandled exception is governed by `SaifStandardProgramBase` and `ConsoleBase` in `SAIF.Framework.Windows`*.

| Failure | Surfaces as | Consumer action |
| --- | --- | --- |
| Service unreachable or SOAP fault returned | A `System.ServiceModel` exception; the specific type is not distinguished in source | Logged by message and rethrown; the run stops |
| Timeout exceeded | A `System.TimeoutException` after the transport default wait* | Same as above |
| Missing endpoint setting key | `ApplicationException` raised by `GetConfigSetting` before the proxy constructor runs | Not handled; fails during container resolution, before the batch loop |
| Present-but-empty endpoint setting value | An argument or URI exception at proxy construction* | Not handled; fails before the batch loop |

## Usage examples

```csharp
// One batch: archive, log the returned identifier, then mark the batch processed
long onbaseId = _onbaseService.ProcessRetention(batch.Select(x => x.ClaimNumber).ToArray());
LogService.Write($"Claims sent to OnBase for Retention Processing.  OnBase Document ID: {onbaseId}");
var retentionIds = batch.Select(x => x.Id).ToArray();
_imagingClient.MarkRetentionClaimsAsProcessed(retentionIds);
```

| Scenario | Operations used | Notes |
| --- | --- | --- |
| Process one batch of claim numbers in `ThirdPartyRetentionProcessor.Execute` | `ArchiveDocument` | Called through `IOnBaseService.ProcessRetention`; see [Business rules](business-rules.md) |

## Lifecycle guidance

| Question | Answer |
| --- | --- |
| Construct once or per call | Once per run. The wrapper is resolved once in `Program.CreateApplication` and reused across every batch |
| Disposable | No |
| Safe to share across threads | Not determined from source** |

## Related documentation
- [Client index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Contract](contract.md)
- [Operation map](operation-map.md)
- [Client reference](reference.md)
- [Dependencies](dependencies.md)
- [Business rules](business-rules.md)
- [Tech debt](tech-debt.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- ProcessOB3PRetention/Services/OnBaseService.cs
- ProcessOB3PRetention/ThirdPartyRetentionProcessor.cs
- ProcessOB3PRetention/Program.cs
- ProcessOB3PRetention/App.config
- ProcessOB3PRetention/ProcessOB3PRetention.csproj
- ProcessOB3PRetention/Connected Services/OBRetentionService/Reference.svcmap
- environmentSettings/settings.yml
